package com.fjwt.gz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.core.cache.RedisUtil;
import com.fjwt.gz.core.constants.ApiCodeEnum;
import com.fjwt.gz.db.bo.ActivityAwardAndSettingBo;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.utils.SpringBeansUtil;
import com.fjwt.gz.db.bo.AwardUserTimesBO;
import com.fjwt.gz.db.dto.ScoreRecordDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.ScoreRecordTotalVO;
import com.fjwt.gz.interfaces.BaseScoreRecodService;
import com.fjwt.gz.service.mapper.AgentScoreRuleMapper;
import com.fjwt.gz.service.mapper.AwardSettingMapper;
import com.fjwt.gz.service.mapper.ScoreRecordTotalMapper;
import com.fjwt.gz.service.mapper.ScoreTotalMapper;
import com.fjwt.gz.util.JsonUtils;
import com.fjwt.gz.util.Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;

import java.util.*;

/**
 * <p>
 * 积分变动记录汇总表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class ScoreRecordTotalService extends ServiceImpl<ScoreRecordTotalMapper, ScoreRecordTotalEntity> {

    @Autowired
    private AgentScoreService agentScoreService;
    @Autowired
    private ScoreRecordTotalMapper scoreRecordTotalMapper;
    @Autowired
    private ScoreTotalService scoreTotalService;
    @Autowired
    private ScoreTotalMapper scoreTotalMapper;
    @Autowired
    private AgentScoreRuleMapper agentScoreRuleMapper;
    @Autowired
    private ScoreRecordTotalService scoreRecordTotalService;
    @Autowired
    private ScoreRecordTotalMapper recordTotalMapper;
    @Autowired
    private ScoreExchangeService scoreExchangeService;
    @Autowired
    private AwardVirtualService awardVirtualService;
    @Autowired
    private AwardVirtualInsideService awardVirtualInsideService;
    @Autowired
    private AwardVirtualCdkService awardVirtualCdkService;
    @Autowired
    private AwardSettingMapper awardSettingMapper;
    @Autowired
    private SendAwardService sendAwardService;
    @Autowired
    private AwardCouponService awardCouponService;
    @Autowired
    private AwardSettingService awardSettingService;
    @Autowired
    private ActivityAwardService activityAwardService;
    @Autowired
    private AwardGoodsService awardGoodsService;
    @Autowired
    private FansService fansService;
    @Autowired
    private BlacklistRuleService blackListRuleService;
    @Autowired
    private AgentAppService agentAppService;

    /**
     * 发放积分
     * <p>
     * scoreRecordTotalEntity参数必传的字段是
     * fansId;
     * appId;
     * infoId; 积分规则ID、活动ID、活动积分奖品ID、兑换的卡券ID、兑换的实物奖品ID、兑换的虚拟券ID
     * infoType; 规则RULE、活动ACTIVITY、活动积分奖品AWARD、卡券COUPON、实物奖品GOODS、虚拟券VIRTUAL
     * name;
     * score;
     * flag;
     * activityId;
     * activityChannelId;//通过活动渠道码参与的活动需要加入
     * overTime;    overType = 1【指定时间】必传
     **/
    @Transactional
    public Boolean addScoreRecordTotal(String agentNo, ScoreRecordTotalEntity scoreRecordTotalEntity, int overDays, int overType, Date overTime) throws BizException {
        log.info("开始进入发放积分，进来的信息是，agentNo：{}，scoreRecordTotalEntity：{}，overDays：{}，overType：{}，overTime：{}",
                agentNo, JSONUtil.toJsonStr(scoreRecordTotalEntity), overDays, overType, overTime);
        Date date = new Date();
        //通过机构号查询机构类别
        AgentScoreEntity agentScoreByAgentNo = agentScoreService.getAgentScoreByAgentNo(agentNo);
        log.info("查询出来的机构类别信息是：{}", JSONUtil.toJsonStr(agentScoreByAgentNo));

        //添加积分动作表
        addScoreRecordTotal(scoreRecordTotalEntity, agentScoreByAgentNo, date);
        //添加积分明细表
        addScoreRecord(scoreRecordTotalEntity, overDays, overType, overTime, date, agentScoreByAgentNo);
        // 添加或更新总积分
        return saveOrUpdateScoreReordTotol(scoreRecordTotalEntity, date, agentScoreByAgentNo);
    }

    /**添加或更新总积分**/
    private boolean saveOrUpdateScoreReordTotol(ScoreRecordTotalEntity scoreRecordTotalEntity, Date date, AgentScoreEntity agentScoreByAgentNo) {
        LambdaQueryWrapper<ScoreTotalEntity> gw = ScoreTotalEntity.gw();
        gw.eq(ScoreTotalEntity::getFansId, scoreRecordTotalEntity.getFansId());
        gw.eq(ScoreTotalEntity::getAppId, scoreRecordTotalEntity.getAppId());
        ScoreTotalEntity scoreTotalEntity = scoreTotalService.getOne(gw);
        if (scoreTotalEntity == null) {
            scoreTotalEntity = new ScoreTotalEntity();
            scoreTotalEntity.setFansId(scoreRecordTotalEntity.getFansId());
            scoreTotalEntity.setCreatedAt(date);
            scoreTotalEntity.setCurrentScore(0);
            scoreTotalEntity.setAppId(scoreRecordTotalEntity.getAppId());
            scoreTotalEntity.setAgentScoreId(agentScoreByAgentNo.getAgentScoreId());
        } else {
            scoreTotalEntity.setUpdatedAt(date);
        }
        scoreTotalEntity.setCurrentScore(scoreTotalEntity.getCurrentScore() + scoreRecordTotalEntity.getScore());
        log.info("用户fansId：{}，保存或更新数据信息是：{}", scoreRecordTotalEntity.getFansId(), JsonUtils.toJson(scoreTotalEntity));
        return scoreTotalService.saveOrUpdate(scoreTotalEntity);
    }

    /**添加积分明细表**/
    private void addScoreRecord(ScoreRecordTotalEntity scoreRecordTotalEntity, int overDays, int overType, Date overTime, Date date, AgentScoreEntity agentScoreByAgentNo) {
        List<ScoreRecordDTO> list = new ArrayList<>();
        for (int i = 0; i < scoreRecordTotalEntity.getScore(); i++) {
            ScoreRecordDTO scoreRecordDTO = new ScoreRecordDTO();
            scoreRecordDTO.setState(Constants.FANS_AWARD_STATE.UNUSED);
            // 获取积分过期时间
            Date scoreOverTime = getScoreOverTime(overDays, overType, overTime);
            scoreRecordDTO.setOverTime(scoreOverTime);
            scoreRecordDTO.setCreatedAt(date);
            scoreRecordDTO.setAgentScoreId(agentScoreByAgentNo.getAgentScoreId());
            scoreRecordDTO.setScoreAddId(scoreRecordTotalEntity.getScoreRecordTotalId());
            scoreRecordDTO.setAppId(scoreRecordTotalEntity.getAppId());
            scoreRecordDTO.setFansId(scoreRecordTotalEntity.getFansId());
            list.add(scoreRecordDTO);
        }

        long fansNum = scoreRecordTotalEntity.getFansId() % 8;
        log.info("{}，客户fansId，产生福分，得到分表的信息：{}", scoreRecordTotalEntity.getFansId(), fansNum);
        // TODO 产生福分 根据分表 进行操作数据
        String serviceName = "scoreRecord0" + fansNum + "Service";
        BaseScoreRecodService scoreRecodService = SpringBeansUtil.getBean(serviceName, BaseScoreRecodService.class);
        int i = scoreRecodService.addScore(list);
        if (i != scoreRecordTotalEntity.getScore()) {
            log.error("积分明细添加失败");
            throw new BizException("新增积分失败");
        }
    }

    /**添加积分动作表**/
    private void addScoreRecordTotal(ScoreRecordTotalEntity scoreRecordTotalEntity, AgentScoreEntity agentScoreByAgentNo, Date date) {
        scoreRecordTotalEntity.setAgentScoreId(agentScoreByAgentNo.getAgentScoreId());
        int randomNum =  1000 + new Random().nextInt(9000);
        String str = scoreRecordTotalEntity.getFansId() + "_" + scoreRecordTotalEntity.getInfoId() + "_" + scoreRecordTotalEntity.getInfoType()
                + "_" + DateUtil.format(date, DatePattern.PURE_DATETIME_MS_PATTERN+ "_" + randomNum);
        scoreRecordTotalEntity.setUniqueKey(str);
        scoreRecordTotalEntity.setCreatedAt(date);
        scoreRecordTotalMapper.insert(scoreRecordTotalEntity);
    }

    /**获取积分过期时间**/
    public Date getScoreOverTime(int overDays, int overType, Date overTime) {
        if (2 == overType) {
            return Utils.firstMonthLastDay();
        } else if (1 == overType) {
            return overTime;
        } else {
            Date today = new Date();
            //计算n天后的日期
            Date futureDate = DateUtil.offsetDay(today, overDays-1);
            //计算n天后的最后一秒时间
            Date futureEndTime = DateUtil.endOfDay(futureDate);
            return futureEndTime;
        }
    }

    /**
     * 检验是否签到
     * @param fansId
     * @param infoType
     * @return 1存在签到记录，0不存在签到记录
     */
    public JSONObject checkSign(Long fansId,Long infoId,String infoType) {
        if(fansId == null || infoId == null){
            throw new BizException("网络故障，请稍后重试！");
        }
        List<ScoreRecordTotalEntity> recordTotalEntityList = scoreRecordTotalMapper.checkSign(fansId,infoId,infoType);
        JSONObject json = new JSONObject();
        if(ObjectUtils.isEmpty(recordTotalEntityList)){
            json.put("flag","true");
        }else{
            json.put("flag","false");
        }
        return json;
    }

    /**
     * 福分生成
     */
    @Transactional(rollbackFor = Exception.class)
    public int scoreRecordGenerate(Long fansId, Long ruleId, String name, String infoType, JSONObject json, String appId) {
        log.info("用户获取积分：规则id：{}", ruleId);
        // 查询积分规则
        AgentScoreRuleEntity agentScoreRuleEntity = agentScoreRuleMapper.selectById(ruleId);
        log.info("积分规则明细：{}", JSON.toJSONString(agentScoreRuleEntity));
        // 查询总积分
        ScoreTotalEntity totalEntity = scoreTotalMapper.selectByFansId(fansId, appId);
        log.info("查询用户积分总数：{}", JSON.toJSONString(totalEntity));
        int m = 0;
        int n = 0;

        long fansNum = fansId % 8;
        log.info("客户fansId：{}，产生福分得到分表的信息：{}", fansId, fansNum);
        // TODO 产生福分 根据分表 进行操作数据
        String serviceName = "scoreRecord0" + fansNum + "Service";
        BaseScoreRecodService scoreRecordService = SpringBeansUtil.getBean(serviceName, BaseScoreRecodService.class);
        if (ObjectUtils.isEmpty(scoreRecordService)){
            log.info("{}，客户fansId，产生福分得到分表信息Service失败：{}", fansId, scoreRecordService);
            return 1;
        }
        // 积分明细对象
        ScoreRecordDTO entity = new ScoreRecordDTO();
        entity.setCreatedAt(new Date());
        if (Constants.SCORE_EXPIRED_TYPE.NEXT_QUARTER == agentScoreRuleEntity.getOverType()) {
            entity.setOverTime(Utils.firstMonthLastDay());
        } else if (Constants.SCORE_EXPIRED_TYPE.SET_TIME == agentScoreRuleEntity.getOverType()) {
            entity.setOverTime(agentScoreRuleEntity.getOverTime());
        } else {
            Integer overDays = agentScoreRuleEntity.getOverDays();
            Date today = new Date();
            //计算n天后的日期
            Date futureDate = DateUtil.offsetDay(today, overDays-1);
            //计算n天后的最后一秒时间
            Date futureEndTime = DateUtil.endOfDay(futureDate);
            entity.setOverTime(futureEndTime);
        }
        Date date = new Date();
        // 添加获取积分记录信息
        ScoreRecordTotalEntity recordTotalEntity = new ScoreRecordTotalEntity();
        setScore(recordTotalEntity, agentScoreRuleEntity, fansId);
        recordTotalEntity.setAppId(appId);
        recordTotalEntity.setFansId(fansId);
        recordTotalEntity.setFlag(Constants.SCORE_FLAG.ADD);
        recordTotalEntity.setName(name);
        recordTotalEntity.setInfoId(agentScoreRuleEntity.getScoreRuleId());
        recordTotalEntity.setInfoType(infoType);
        recordTotalEntity.setCreatedAt(date);
        String uniqueKey;
        if(1 == ruleId.intValue() && "RULE".equals(infoType)){
            uniqueKey = fansId+"_"+ruleId+"_"+infoType+"_"+DateUtil.format(date, DatePattern.PURE_DATE_PATTERN);
        }else if(2 == ruleId.intValue() && "RULE".equals(infoType)){
            uniqueKey = fansId+"_"+ruleId+"_"+infoType;
        }else{
            uniqueKey = fansId+"_"+ruleId+"_"+infoType+"_"+DateUtil.format(date,DatePattern.PURE_DATETIME_MS_PATTERN);
        }
        recordTotalEntity.setUniqueKey(uniqueKey);
        recordTotalEntity.setAgentScoreId(agentScoreRuleEntity.getAgentScoreId());
        if(null != json){
            recordTotalEntity.setActivityChannelId(json.getLong("activityChannelId"));
            recordTotalEntity.setActivityId(json.getLong("activityId"));
        }
        scoreRecordTotalService.saveOrUpdate(recordTotalEntity);
        entity.setState(0);
        entity.setScoreAddId(recordTotalEntity.getScoreRecordTotalId());
        entity.setFansId(fansId);
        entity.setAgentScoreId(agentScoreRuleEntity.getAgentScoreId());
        entity.setRemark(name);
        if (1 == recordTotalEntity.getScore()) {
            List<ScoreRecordDTO> list = new ArrayList<>();
            list.add(entity);
            m = scoreRecordService.addScore(list);
        } else {
            int value = recordTotalEntity.getScore();
            List<ScoreRecordDTO> list = new ArrayList<>();
            for (int i = 0; i < value; i++) {
                ScoreRecordDTO result = new ScoreRecordDTO();
                BeanUtils.copyProperties(entity, result);
                result.setAppId(appId);
                list.add(result);
            }
            m = scoreRecordService.addScore(list);
        }

        if (m != recordTotalEntity.getScore()) {
            log.error("积分明细添加失败");
            throw new BizException("新增积分失败");
        }

        if (Objects.isNull(totalEntity)) {
            ScoreTotalEntity dto = new ScoreTotalEntity();
            dto.setAppId(appId);
            dto.setCurrentScore(recordTotalEntity.getScore());
            dto.setFansId(entity.getFansId());
            dto.setCreatedAt(new Date());
            dto.setAgentScoreId(agentScoreRuleEntity.getAgentScoreId());
            log.info("用户总积分计算：{}", JSON.toJSONString(dto));
            n = scoreTotalMapper.insert(dto);
        } else {
            ScoreTotalEntity dto = new ScoreTotalEntity();
            dto.setAppId(appId);
            dto.setScoreTotalId(totalEntity.getScoreTotalId());
            Integer num = recordTotalEntity.getScore() + totalEntity.getCurrentScore();
            dto.setCurrentScore(num);
            dto.setUpdatedAt(new Date());
            dto.setAgentScoreId(agentScoreRuleEntity.getAgentScoreId());
            log.info("用户总积分计算：{}", JSON.toJSONString(dto));
            n = scoreTotalMapper.updateById(dto);
        }
        return n;
    }

    /**
     * 校验用户是否连续签到
     *
     * @param recordTotalEntity
     * @param ruleEntity
     * @param fansId
     */
    public void setScore(ScoreRecordTotalEntity recordTotalEntity, AgentScoreRuleEntity ruleEntity, Long fansId) {
        String ruleJson = ruleEntity.getRuleJson();
        JSONObject object = JSONObject.parseObject(ruleJson);
        // 签到获取积分
        if ("sign".equals(ruleEntity.getRuleKey())) {
            // 校验是否连续签到
            if (ruleEntity.getRuleJson().contains("period") && ruleEntity.getRuleJson().contains("signLink")) {
                int day = object.getInteger("period");
                int i = scoreRecordTotalService.checkSignLink(fansId,ruleEntity.getScoreRuleId(),Constants.SCORE.RULE, day - 1);
                if (i != (day - 1)) {
                    recordTotalEntity.setScore(object.getInteger(ruleEntity.getRuleKey()));
                } else {
                    recordTotalEntity.setScore(object.getInteger("signLink"));
                }
            } else {
                recordTotalEntity.setScore(object.getInteger(ruleEntity.getRuleKey()));
            }
        } else {
            recordTotalEntity.setScore(object.getInteger(ruleEntity.getRuleKey()));
        }
    }

    /**
     * 校验用户是否连续签到
     * @param fansId
     * @param ruleKey
     * @return
     */
    public int checkSignLink(Long fansId,Long ruleId,String ruleKey,int day) {
        return recordTotalMapper.checkSignLink(fansId,ruleId,ruleKey,day);
    }

    /**
     * 查询用户签到记录
     * @param fansId
     * @param ruleId
     * @param infoType
     * @param time
     * @return
     */
    public List<ScoreRecordTotalEntity> findSignRecordList(Long fansId, Long ruleId, String infoType, String time) {
        if(ruleId == null){
            ruleId = 1L;
        }
        if(Objects.isNull(fansId) || StringUtils.isEmpty(infoType) || StringUtils.isEmpty(time)){
            throw new BizException("网络故障，请稍后重试！");
        }
        return baseMapper.findSignRecordList(fansId,ruleId,infoType,time);
    }

    /**
     * 获取当天获得福分总量
     * @param fansId
     * @return
     */
    public int getUserScoreSum(Long fansId, String appId) {
        if(fansId == null){
            throw new BizException("网络故障，请稍后重试！");
        }
        return baseMapper.getUserScoreSum(fansId, appId);
    }

    /**
     * 校验过期积分
     **/
    public void checkOffScore(Long fansId, String name, String appId) {
        long fansNum = fansId % 8;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String overDate = simpleDateFormat.format(new Date());
        // 用户主动消耗积分时查询过期积分list
        String serviceName = "scoreRecord0" + fansNum + "Service";
        log.info("用户的积分明细表的积分Service为：{},fansId:{}", serviceName, fansId);
        BaseScoreRecodService scoreRecodService = SpringBeansUtil.getBean(serviceName, BaseScoreRecodService.class);
        if (ObjectUtils.isEmpty(scoreRecodService)){
            log.info("未查询到用户的积分明细表的积分Service：{},用户fansId：{}", serviceName, fansId);
            return;
        }
        List<ScoreRecordDTO> offScoreRecords = scoreRecodService.selectOffRecordList(fansId, overDate, null);
        List<ScoreRecordDTO> dtos = List.copyOf(offScoreRecords);
        if (dtos == null || dtos.size() <= 0) {
            log.info("当前没有过期积分明细");
            return;
        }
        // 过期积分处理
        Date date = new Date();
        ScoreRecordTotalEntity scoreRecordTotalEntity = new ScoreRecordTotalEntity();
        scoreRecordTotalEntity.setName(name);
        scoreRecordTotalEntity.setScore(dtos.size());
        scoreRecordTotalEntity.setFlag(2);
        scoreRecordTotalEntity.setCreatedAt(date);
        scoreRecordTotalEntity.setFansId(fansId);
        scoreRecordTotalEntity.setAgentScoreId(1L);
        scoreRecordTotalEntity.setAppId(appId);
        String str = fansId+"_"+"NULL"+"_"+"OVERTIME"+DateUtil.format(date,DatePattern.PURE_DATETIME_MS_PATTERN);
        scoreRecordTotalEntity.setUniqueKey(str);
        scoreRecordTotalMapper.insert(scoreRecordTotalEntity);
        log.info("积分动作记录表新增完成");
        LambdaQueryWrapper<ScoreTotalEntity> gw = ScoreTotalEntity.gw();
        gw.eq(ScoreTotalEntity::getFansId, fansId);
        gw.eq(ScoreTotalEntity::getAppId, appId);
        ScoreTotalEntity scoreTotalDb = scoreTotalService.getOne(gw);
        Integer currentScore = scoreTotalDb.getCurrentScore();
        Integer nowScore = currentScore - dtos.size();
        scoreTotalDb.setCurrentScore(nowScore);
        scoreTotalDb.setUpdatedAt(new Date());
        scoreTotalService.updateById(scoreTotalDb);
        log.info("积分总表去掉过期积分更新完毕");
        scoreRecodService.updateBatchOffScore(dtos, 2,fansId);
        log.info("积分明细过期更新完毕");
    }

    /**
     * 核销福分，兑换卡券/实物
     */
    @Transactional(rollbackFor = Exception.class)
    public int scoreRecordDestroy(Long fansId, String exchangeId, Integer infoType, String name, String agentNo, String appId) {
        FansEntity fansEntity = fansService.getById(fansId);
        if (ObjectUtils.isEmpty(fansEntity)) {
            throw new BizException(ApiCodeEnum.LITE_USER_ERROR);
        }

        log.info("用户fansId：{}，兑换id：{}，兑换类型：{}", fansId, exchangeId, infoType);
        ScoreTotalEntity totalEntity = scoreTotalMapper.selectByFansId(fansId, appId);
        log.info("用户总积分信息：{}", JSON.toJSONString(totalEntity));
        if (Objects.isNull(totalEntity)) {
            throw new BizException("未获取用户可用积分！");
        }
        ScoreExchangeEntity exchangeEntity = scoreExchangeService.getById(Long.parseLong(exchangeId));
        log.info("兑换礼品信息：{}", JSON.toJSONString(exchangeEntity));
        if (exchangeEntity.getHasBlacklist() == 1) {
            // 黑名单校验
            checkBlacklist(fansEntity, exchangeEntity, appId);
        }
        Integer score = totalEntity.getCurrentScore();
        Integer scoreNeed = exchangeEntity.getScoreNeed();
        if (score < scoreNeed) {
            throw new BizException("所需积分不够，请核实积分！");
        }
        long fansNum = fansId % 8;
        log.info("{}，用户的fansId,兑换卡券奖品得到的分表信息：{}", fansId, fansNum);

        String typeName = "";
        if (Constants.AWARD.COUPON == infoType) {
            typeName = Constants.SCORE.COUPON;
        }else if (Constants.AWARD.GOODS == infoType) {
            typeName = Constants.SCORE.GOODS;
        }else if (Constants.AWARD.VIRTUAL_COUPON == infoType) {
            typeName = Constants.SCORE.VIRTUAL;
        }else {
            throw new BizException("兑换类型异常，请检查");
        }

        JSONObject extraJson = new JSONObject();
        // 添加用户消耗积分记录
        Date date = new Date();
        ScoreRecordTotalEntity consumeEntity = new ScoreRecordTotalEntity();
        consumeEntity.setScore(exchangeEntity.getScoreNeed());
        consumeEntity.setFlag(1);
        consumeEntity.setName("兑换" + name);
        consumeEntity.setCreatedAt(date);
        consumeEntity.setInfoType(typeName);
        String str = fansId+"_"+exchangeEntity.getAwardId()+"_"+typeName+"_"+DateUtil.format(date,DatePattern.PURE_DATETIME_MS_PATTERN);
        consumeEntity.setUniqueKey(str);
        // 积分商城，对应的奖品id
        consumeEntity.setInfoId((exchangeEntity.getAwardId()));
        consumeEntity.setFansId(fansId);
        consumeEntity.setAgentScoreId(totalEntity.getAgentScoreId());
        consumeEntity.setAppId(appId);
        log.info("用户积分兑换信息：{}", JSON.toJSONString(consumeEntity));
        int i = recordTotalMapper.insert(consumeEntity);
        if (i > 0) {
            // 更新获取积分明细数据
            String serviceName = "scoreRecord0" + fansNum + "Service";
            log.info("用户的积分明细表的积分Service为：{},fansId:{}", serviceName, fansId);
            BaseScoreRecodService scoreRecodService = SpringBeansUtil.getBean(serviceName, BaseScoreRecodService.class);
            if (ObjectUtils.isEmpty(scoreRecodService)){
                throw new BizException("未查询到用户的积分明细表的积分Service：" + serviceName + ",用户fansId：" + fansId);
            }
            List<ScoreRecordDTO> list = scoreRecodService.selectOffRecordList(fansId, null, scoreNeed);
            List<ScoreRecordDTO> dtos = List.copyOf(list);
            scoreRecodService.updateBatchOffScore(dtos, 1,fansId);
            // 更新积分总数据
            ScoreTotalEntity totalResult = new ScoreTotalEntity();
            totalResult.setAppId(appId);
            totalResult.setScoreTotalId(totalEntity.getScoreTotalId());
            totalResult.setCurrentScore(score - scoreNeed);
            totalResult.setUpdatedAt(new Date());
            log.info("用户总积分信息：{}", JSON.toJSONString(totalResult));
            i = scoreTotalMapper.updateById(totalResult);
        }
        if (i > 0) {
            Long redisOutTime = null;
            String awardName = null;
            // 发放A奖品
            ActivityAwardAndSettingBo activityAwardAndSettingBo = new ActivityAwardAndSettingBo();

            if (Constants.AWARD.COUPON == exchangeEntity.getAwardType()) {
                AwardCouponEntity awardCouponEntity = awardCouponService.getById(exchangeEntity.getAwardId());
                if (ObjectUtils.isEmpty(awardCouponEntity)) {
                    throw new BizException("奖品异常！");
                }
                awardName = awardCouponEntity.getCouponName();
                redisOutTime = awardCouponEntity.getEndTime().getTime() - System.currentTimeMillis();
                AwardSettingEntity awardSetting = findAwardSetting(exchangeEntity.getAwardId(), Constants.AWARD.COUPON);
                BeanUtils.copyProperties(awardSetting, activityAwardAndSettingBo);
            }else if (Constants.AWARD.GOODS == exchangeEntity.getAwardType()) {
                AwardGoodsEntity awardGoodsEntity = awardGoodsService.getById(exchangeEntity.getAwardId());
                if (ObjectUtils.isEmpty(awardGoodsEntity)) {
                    throw new BizException("奖品异常！");
                }
                awardName = awardGoodsEntity.getGoodsName();
                AwardSettingEntity awardSetting = findAwardSetting(exchangeEntity.getAwardId(), Constants.AWARD.GOODS);
                BeanUtils.copyProperties(awardSetting, activityAwardAndSettingBo);
            }else if (Constants.AWARD.VIRTUAL_COUPON == exchangeEntity.getAwardType()) {
                AwardSettingEntity awardSetting = findAwardSetting(exchangeEntity.getAwardId(), Constants.AWARD.VIRTUAL_COUPON);
                BeanUtils.copyProperties(awardSetting, activityAwardAndSettingBo);

                AwardVirtualEntity virtualAwardEntity = awardVirtualService.getById(exchangeEntity.getAwardId());
                if (ObjectUtils.isEmpty(virtualAwardEntity)) {
                    throw new BizException("奖品异常！");
                }
                AwardVirtualInsideEntity goodsInsideEntity = awardVirtualInsideService.getById(virtualAwardEntity.getVirtualInsideId());
                if (ObjectUtils.isEmpty(goodsInsideEntity)) {
                    throw new BizException("奖品异常！");
                }
                awardName = goodsInsideEntity.getGoodsName();
                if (0 == goodsInsideEntity.getType()) {
                    // 匹配对应cdk
                    LambdaQueryWrapper<AwardVirtualCdkEntity> gw = AwardVirtualCdkEntity.gw()
                            .eq(AwardVirtualCdkEntity::getVirtualId, virtualAwardEntity.getVirtualId())
                            .eq(AwardVirtualCdkEntity::getAgentNo, virtualAwardEntity.getAgentNo())
                            .eq(AwardVirtualCdkEntity::getIsConsume, 0)
                            .orderByAsc(AwardVirtualCdkEntity::getVirtualCdkId);
                    List<AwardVirtualCdkEntity> awardCdkEntityList = awardVirtualCdkService.list(gw);
                    if (ObjectUtils.isEmpty(awardCdkEntityList)) {
                        throw new BizException("当前奖品已无库存，您可以兑换其他奖品");
                    }
                    AwardVirtualCdkEntity awardCdkEntity = awardCdkEntityList.get(0);
                    extraJson.put("cdk", awardCdkEntity.getCdk());
                    awardCdkEntity.setIsConsume(1);
                    awardVirtualCdkService.updateById(awardCdkEntity);
                }
            }
            activityAwardAndSettingBo.setAwardName(awardName);
            activityAwardAndSettingBo.setRemark("福分兑换所获得的奖品！");
            // 检查用户参与限制
            JSONObject awardCheckJson = awardSettingService.AwardSettingRule(fansId, agentNo, activityAwardAndSettingBo);

            // 发放奖品
            sendAwardService.sendCouponOrGoods(fansId, appId, activityAwardAndSettingBo, exchangeEntity.getPayAuthId(),null, true, JSONObject.toJSONString(extraJson));

            //更新Redis中参与的次数
            awardSettingService.updateAwardLimitCache(awardCheckJson, redisOutTime);
        }
        return i;
    }

    /**
     * 查询奖品派发限制
     */
    public AwardSettingEntity findAwardSetting(Long awardId, Integer awardType) {
        LambdaQueryWrapper<AwardSettingEntity> gw = AwardSettingEntity.gw();
        gw.eq(AwardSettingEntity::getAwardId, awardId);
        gw.eq(AwardSettingEntity::getAwardType, awardType);
        AwardSettingEntity awardSettingEntity = awardSettingMapper.selectOne(gw);
        if (ObjectUtils.isEmpty(awardSettingEntity)) {
            return null;
        }
        return awardSettingEntity;
    }

    /**
     * 获取用户新增，消耗积分记录
     * @param fansId
     * @param flag
     * @return
     */
    public IPage<ScoreRecordTotalVO> findFansScoreRecord(IPage iPage, Long fansId, String flag, String appId) {
        if(Objects.isNull(fansId) || Objects.isNull(appId)){
            throw new BizException("网络故障，请稍后重试！");
        }
        IPage<ScoreRecordTotalEntity> fansScoreRecord = recordTotalMapper.findFansScoreRecord(iPage, fansId, flag, appId);
        IPage<ScoreRecordTotalVO> page = fansScoreRecord.convert(e -> {
            ScoreRecordTotalVO vo = BeanUtil.copyProperties(e, ScoreRecordTotalVO.class);
            return vo;
        });
        return page;
    }

    /**
     * 获取用户兑换记录
     * @param iPage
     * @param fansId
     * @param flag
     * @return
     */
    public IPage<ScoreRecordTotalEntity> getExchangeScore(IPage iPage, Long fansId, String flag) {
        if(Objects.isNull(fansId) || StringUtils.isEmpty(flag)){
            throw new BizException("网络故障，请稍后重试！");
        }
        return recordTotalMapper.getExchangeScore(iPage, fansId, flag);
    }

    /**
     * 获取用户积分记录
     * @param iPage
     * @param phone
     * @param nickName
     * @return
     */
    public IPage<ScoreRecordTotalVO> getFansScoreRecord(IPage iPage, String phone, String nickName,String sTime,String eTime) {
        return recordTotalMapper.getFansScoreRecord(iPage,phone,nickName,sTime,eTime);
    }

    /**
     * 检验用户是否实名
     * @param fansId
     * @param infoType
     * @return
     * 1存在实名记录，0不存在实名记录
     */
    public JSONObject checkAuth(Long fansId, String infoType) {
        if(Objects.isNull(fansId) || StringUtils.isEmpty(infoType)){
            throw new BizException("网络故障，请稍后重试！");
        }
        ScoreRecordTotalEntity recordTotalEntity = recordTotalMapper.checkAuth(fansId, infoType);
        JSONObject json = new JSONObject();
        if(Objects.isNull(recordTotalEntity)){
            json.put("flag","true");
        }else{
            json.put("flag","false");
        }
        return json;
    }

    /**核销后奖励福分**/
    public void couponWriteSendScore(FansAwardEntity fansAwardEntity) {
        AwardCouponEntity awardEntity = awardCouponService.getById(fansAwardEntity.getAwardId());
        if(null != awardEntity){
            log.info("卡券核销，此时卡券配置信息：{}",JSONObject.toJSONString(awardEntity));
            //查询奖品设置表
            LambdaQueryWrapper<AwardSettingEntity> gw = AwardSettingEntity.gw();
            gw.eq(AwardSettingEntity::getAwardId, fansAwardEntity.getAwardId());
            gw.eq(AwardSettingEntity::getAwardType, fansAwardEntity.getAwardType());
            AwardSettingEntity awardSettingEntity = awardSettingService.getOne(gw);
            if (awardSettingEntity.getVerifiedScore() > 0){
                //查询奖品关联的活动ID
                LambdaQueryWrapper<ActivityAwardEntity> activityAwargw = ActivityAwardEntity.gw();
                activityAwargw.eq(ActivityAwardEntity::getAwardId, fansAwardEntity.getAwardId());
                activityAwargw.eq(ActivityAwardEntity::getAwardType, fansAwardEntity.getAwardType());
                ActivityAwardEntity activityAwardServiceOne = activityAwardService.getOne(activityAwargw);

                ScoreRecordTotalEntity scoreRecordTotalEntity = new ScoreRecordTotalEntity();
                scoreRecordTotalEntity.setScore(awardSettingEntity.getVerifiedScore());
                scoreRecordTotalEntity.setName("使用权益卡券获得福分");
                scoreRecordTotalEntity.setFlag(0);
                scoreRecordTotalEntity.setInfoId(awardSettingEntity.getAwardId());
                scoreRecordTotalEntity.setInfoType("FANS_AWARD");
                scoreRecordTotalEntity.setAppId(fansAwardEntity.getAppId());
                scoreRecordTotalEntity.setFansId(fansAwardEntity.getFansId());
                scoreRecordTotalEntity.setActivityId(activityAwardServiceOne.getActivityId());
                if (null != awardSettingEntity.getScoreOverTime() && awardSettingEntity.getScoreOverType() == 1){
                    scoreRecordTotalEntity.setOverTime(awardSettingEntity.getScoreOverTime());
                }

                // 根据appId查询对应的机构
                AgentAppEntity agentAppEntity = agentAppService.getOne(
                        AgentAppEntity.gw()
                                .eq(AgentAppEntity::getAppId, fansAwardEntity.getAppId())
                );

                this.addScoreRecordTotal(agentAppEntity.getAgentNo(), scoreRecordTotalEntity,awardSettingEntity.getScoreOverDays(),
                        awardSettingEntity.getScoreOverType(), awardSettingEntity.getScoreOverTime());
            }
        }
    }

    private void checkBlacklist(FansEntity fansEntity, ScoreExchangeEntity scoreExchangeEntity, String appId) {
        Long redisOutTime = 60 * 1000000L;
        Long scoreExchangeId = scoreExchangeEntity.getScoreExchangeId();
        log.info("当前积分兑换id:{}", scoreExchangeId);
        //查询是否存在黑名单规则
        List<BlacklistRuleEntity> scoreBlacRulesList = blackListRuleService.getScoreBlacRulesList(scoreExchangeId, redisOutTime);
        log.info("当前积分兑换黑名单规则，{}", scoreBlacRulesList);
        blackListRuleService.commonBlacklistRuleValid(scoreBlacRulesList, fansEntity, scoreExchangeId, 1, redisOutTime, appId);
    }

    /**
     * 获取积分记录
     *
     * @param time
     * @return
     */
    public List<ScoreRecordTotalVO> selectDailyScoreRecords(String time) {
        return baseMapper.selectDailyScoreRecords(time);
    }

    public List<Map<String, Object>> getScoreCount(List<Long> acteIdList, List<Long> fansIdList, List<String> appIdList) {
        return this.scoreRecordTotalMapper.getScoreCount(acteIdList, fansIdList, appIdList);
    }
}
